# -*- coding: utf-8 -*-
from flask import Blueprint, request, session
from model import Blog, FollowTable
from exts import cache, db
from utils import restful
from utils.redis import Redis
from decorator import login_required
from setting import Prefixs
from .common import queryUserCache, get_error
from form.blog import blogForm
import time
from model import User
from sqlalchemy import func,case

bp = Blueprint('blog', __name__, url_prefix='/blog')


@bp.route('/publish', methods=['POST'], strict_slashes=False)
@login_required
def upload_blog():
    form = blogForm(data=request.json)
    if not form.validate():
        return restful.fail(get_error(form))
    user_info = queryUserCache()
    title = form.title.data
    content = form.content.data
    images_path = form.images.data
    shopId = form.shopId.data
    blog = Blog(title=title, shopId=shopId, userId=user_info['id'], content=content, images=images_path)
    db.session.add(blog)
    db.session.commit()
    # 查询当前用户的所有粉丝
    follow_users = db.session.query(FollowTable.user_id).filter_by(follow_user_id=user_info['id']).all()
    follow_users_id = [item[0] for item in follow_users]
    # 推送
    for follow_user_id in follow_users_id:
        key = "feed:" + str(follow_user_id)
        Redis.zadd(key, {blog.id: int(time.time() * 1000)})  # 时间戳以微秒计算
    return restful.success()


@bp.route('/hot')
def queryHotBlog():
    page = request.args.get("current", default=1, type=int)
    blog_hots = Blog.query.limit(6).offset((page - 1) * 10).all()
    Blog_hot_list = [blog_hot.to_dict() for blog_hot in blog_hots]
    return restful.success(data=Blog_hot_list)


@bp.route("/<int:id>")
def queryBlogById(id):
    blog = db.session.query(Blog).get(id)
    if not blog:
        return restful.fail('当前笔记已经不在了！')
    user = queryUserCache()
    key = Prefixs.userSet_of_blog_prefix + str(id)
    blog = blog.to_dict()
    blog["isLike"] = 1 if Redis.zscore(key, str(user['id'])) else 0
    return restful.success(data=blog)

# 点赞笔记
@bp.route("/like/<int:id>", methods=["PUT", "GET"])
@login_required
def likeBlog(id):
    user = queryUserCache()
    user_id = str(user['id'])
    blog = Blog.query.get(id)
    if not blog:
        return restful.fail("这篇帖子已经不见了！"), 404
    # userSet_of_blog_prefix + blogID 存储用户id代表一个blog中点赞的用户
    key = Prefixs.userSet_of_blog_prefix + str(id)
    if Redis.zscore(key, user_id):  # 代表点过赞了
        # 点赞了，就删除缓存并更新数据库
        Redis.zrem(key, user_id)
        db.session.query(Blog).filter(Blog.id == id).update({'liked': Blog.liked - 1})
    else:
        # 否则说明没有点赞，就把userid放到redis集合中，然后更新数据库
        Redis.zadd(key, {user_id: str(time.time())})
        db.session.query(Blog).filter(Blog.id == id).update({'liked': Blog.liked + 1})
    db.session.commit()
    return restful.success()


@bp.route("/likes/<int:id>", methods=["PUT", "GET"])
@login_required
def queryBlogLikes(id):
    key = Prefixs.userSet_of_blog_prefix + str(id)
    userIds = [int(value) for value in Redis.zrangebyscore(key, "-inf", "+inf")]
    if userIds:
        order_by = {userIds[i]: i for i in range(len(userIds))}
        users = [user.to_dict() for user in User.query.filter(User.id.in_(userIds)).order_by(
            case(value=User.id, whens=order_by)
        ).all()]
    else:
        users = []
    return restful.success(data=users)


@bp.route("/of/me")
@login_required
def queryMyBlog():
    token_key = Prefixs.user_token_prefix + request.headers.get("Authorization", default='')
    user_info = Redis.hgetall(token_key)
    # print(user_info)
    blog_list = Blog.query.filter_by(userId=user_info["id"]).all()
    blog_info_list = [blog.to_dict() for blog in blog_list]
    return restful.success(data=blog_info_list)


@bp.route('/of/user')
@login_required
def queryblog():
    user_id = request.args.get('id')
    current = request.args.get('curren', default=1)
    number = 10
    blogs = Blog.query.filter_by(userId=user_id).offset(number * (current - 1)).limit(number).all()
    blogs = [blog.to_dict() for blog in blogs]
    return restful.success(data=blogs)


# 查询关注推送消息
@bp.route('/of/follow')
@login_required
def query_follow_blog():
    user_info = queryUserCache()
    lastId = request.args.get("lastId")
    offset = request.args.get('offset', default=0)
    key = Prefixs.feed_prefix + user_info['id']
    # 偏移量offset，查询4条数据
    blogs_id_score = Redis.zrevrangebyscore(key, lastId, 0, start=offset, num=4, withscores=True)
    blogs_id = [blog[0].decode('utf-8') for blog in blogs_id_score]
    # 查询所有笔记的详细数据,按时间戳排名查询
    if blogs_id:
        blogs_info = Blog.query.filter(Blog.id.in_(blogs_id)).order_by(
            func.field(Blog.id, *blogs_id)
        ).all()
        blogs_info = [blog.to_dict() for blog in blogs_info]
        # 时间戳列表
        scores = [blog[1] for blog in blogs_id_score]
        # scores为时间戳，找到最小的时间戳有几个，就代表下一次的偏移量
        offset = scores.count(scores[-1])
        return restful.success(data={'list': blogs_info, "minTime": scores[-1], "offset": offset})
    else:
        return restful.fail("已经没有消息了！")

